From 92eb4bd779250e470191a0d36f4a310134fb76c8 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 22 Feb 2007 15:22:16 +0000 Subject: [PATCH] x86: Detect shadow-emulate write to stack from inside the write handler, where we can quite conveniently check whether the access segment is SS. This will only give a false positive for non-stack writes that override the destination segment to SS, which it is probably safe to assume will never happen when the destination is a legitimate page table! For now, instead of bailing and unshadowing just increment a perfctr and we'll see if that increases fast under any reasonable workload. Signed-off-by: Keir Fraser --- xen/arch/x86/mm/shadow/common.c | 4 ++++ xen/arch/x86/mm/shadow/multi.c | 17 ----------------- xen/include/asm-x86/perfc_defn.h | 1 + 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index f74d18a3c6..e3b4821010 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -275,6 +275,10 @@ hvm_emulate_write(enum x86_segment seg, unsigned long addr; int rc; + /* How many emulations could we save if we unshadowed on stack writes? */ + if ( seg == x86_seg_ss ) + perfc_incrc(shadow_fault_emulate_stack); + rc = hvm_translate_linear_addr( seg, offset, bytes, hvm_access_write, sh_ctxt, &addr); if ( rc ) diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index e348bebaa6..a1748058f9 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -2924,23 +2924,6 @@ static int sh_page_fault(struct vcpu *v, SHADOW_PRINTK("emulate: eip=%#lx esp=%#lx\n", (unsigned long)regs->eip, (unsigned long)regs->esp); - /* - * Check whether this looks like a stack operation. If so, unshadow the - * faulting page. We can allow this to fail: if it does fail then we - * carry on and emulate, otherwise we bail immediately. Failure is - * tolerated because this is only a heuristic (e.g., stack segment base - * address is ignored). - */ - if ( unlikely((va & PAGE_MASK) == (regs->esp & PAGE_MASK)) ) - { - gdprintk(XENLOG_DEBUG, "guest stack is on a shadowed frame: " - "%%esp=%#lx, cr2=%#lx, mfn=%#lx\n", - (unsigned long)regs->esp, va, mfn_x(gmfn)); - sh_remove_shadows(v, gmfn, 0 /* thorough */, 0 /* can fail */); - if ( !(mfn_to_page(gmfn)->count_info & PGC_page_table) ) - goto done; - } - emul_ops = shadow_init_emulation(&emul_ctxt, regs); /* diff --git a/xen/include/asm-x86/perfc_defn.h b/xen/include/asm-x86/perfc_defn.h index ba1e32c8fd..054fa0f1af 100644 --- a/xen/include/asm-x86/perfc_defn.h +++ b/xen/include/asm-x86/perfc_defn.h @@ -56,6 +56,7 @@ PERFCOUNTER_CPU(shadow_fault_bail_user_supervisor, PERFCOUNTER_CPU(shadow_fault_emulate_read, "shadow_fault emulates a read") PERFCOUNTER_CPU(shadow_fault_emulate_write, "shadow_fault emulates a write") PERFCOUNTER_CPU(shadow_fault_emulate_failed, "shadow_fault emulator fails") +PERFCOUNTER_CPU(shadow_fault_emulate_stack, "shadow_fault emulate stack write") PERFCOUNTER_CPU(shadow_fault_mmio, "shadow_fault handled as mmio") PERFCOUNTER_CPU(shadow_fault_fixed, "shadow_fault fixed fault") PERFCOUNTER_CPU(shadow_ptwr_emulate, "shadow causes ptwr to emulate") -- 2.30.2